package org.hcyspartnoc.demo.service.traProgram.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.hcyspartnoc.demo.common.core.configuration.DegreeConfiguration;
import org.hcyspartnoc.demo.common.core.configuration.NoumenonConfiguration;
import org.hcyspartnoc.demo.common.core.configuration.RolesConfiguration;
import org.hcyspartnoc.demo.common.core.context.BaseContextHolder;
import org.hcyspartnoc.demo.dao.*;
import org.hcyspartnoc.demo.entity.*;
import org.hcyspartnoc.demo.mapper.major.MajorMapper;
import org.hcyspartnoc.demo.mapper.system.SysRoleMapper;
import org.hcyspartnoc.demo.mapper.traProgram.EntityDictionaryMapper;
import org.hcyspartnoc.demo.mapper.traProgram.NoumenonMapper;
import org.hcyspartnoc.demo.mapper.traProgram.TraProgramMapper;
import org.hcyspartnoc.demo.pojo.dto.traProgram.TraProgramNodeDto;
import org.hcyspartnoc.demo.pojo.dto.traProgram.UpdateNodeDto;
import org.hcyspartnoc.demo.pojo.po.college.CollegePo;
import org.hcyspartnoc.demo.pojo.po.course.CouTeamMebPo;
import org.hcyspartnoc.demo.pojo.po.course.CouTeamPo;
import org.hcyspartnoc.demo.pojo.po.course.CoursePo;
import org.hcyspartnoc.demo.pojo.po.major.MajorPo;
import org.hcyspartnoc.demo.pojo.po.system.SysRolePo;
import org.hcyspartnoc.demo.pojo.po.system.SysUserPo;
import org.hcyspartnoc.demo.pojo.po.traProgram.NoumenonPo;
import org.hcyspartnoc.demo.pojo.po.traProgram.TraProgramPo;
import org.hcyspartnoc.demo.pojo.vo.course.CourseListVo;
import org.hcyspartnoc.demo.pojo.vo.traProgram.NoumenonVO;
import org.hcyspartnoc.demo.pojo.vo.traProgram.TraProgramVO;
import org.hcyspartnoc.demo.pojo.vo.traProgram.VersionVo;
import org.hcyspartnoc.demo.service.traProgram.ITraProgramService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class TraProgramServiceImpl extends ServiceImpl<TraProgramMapper, TraProgramPo> implements ITraProgramService {
    @Resource
    private MajorMapper majorMapper;

    @Resource
    private SysRoleMapper sysRoleMapper;

    @Resource
    private NoumenonMapper noumenonMapper;

    @Resource
    private TraProgramMapper traProgramMapper;

    @Resource
    private MajorDao majorDao;

    @Resource
    private SchemeDao schemeDao;

    @Resource
    private SpecificRequireDao specificRequireDao;

    @Resource
    private SpecificTargetDao specificTargetDao;

    @Resource
    private BackboneCoursesDao backboneCoursesDao;

    @Resource
    private TeachingStepsDao teachingStepsDao;

    @Resource
    private CourseDao courseDao;

    @Resource
    private PointDao pointDao;

    @Resource
    private RolesConfiguration rolesConfiguration;

    @Resource
    private NoumenonConfiguration noumenonConfiguration;

    @Resource
    private DegreeConfiguration degreeConfiguration;


    @Override
    public List<NoumenonVO> getNoumenon() {
        List<NoumenonPo> noumenonPos = noumenonMapper.selectList(null);
        List<NoumenonVO> noumenonVOS = new ArrayList<>();
        for(NoumenonPo noumenonPo : noumenonPos){
            NoumenonVO noumenonVO = BeanUtil.copyProperties(noumenonPo, NoumenonVO.class);
            noumenonVOS.add(noumenonVO);
        }
        return noumenonVOS;
    }

    @Override
    public Scheme getChart(Integer majorVersionId) {
        TraProgramVO traProgramVO = traProgramMapper.selectMajorAndVersion(majorVersionId);
        List<Scheme> schemes = schemeDao.findAll();
        for(Scheme scheme :schemes){
            if(scheme.getVersion().equals(traProgramVO.getVersion() ) &&
                    scheme.getMajor().equals(traProgramVO.getMajorName())){
                scheme.setCode(traProgramVO.getCode());
                scheme.setSeCategory(traProgramVO.getSeCategory());
                scheme.setSuCategory(traProgramVO.getSuCategory());
                scheme.setEducationalSystem(traProgramVO.getEducationalSystem());
                scheme.setAcademicDegree(traProgramVO.getAcademicDegree());
                return scheme;
            }
        }
        return null;
    }

    @Override
    public List<VersionVo> getVersions() {
        // 通过上下文获取当前用户
        SysUserPo currentUser = BaseContextHolder.getContext().getBaseCurrentUser();
        if (currentUser == null) {
            // 如果用户不存在，抛出异常
            throw new RuntimeException("用户不存在");
        }
        SysRolePo sysRolePo = sysRoleMapper.selectById(currentUser.getRoleId());
        if(sysRolePo == null){
            throw new RuntimeException("用户权限错误");
        }
        List<VersionVo> versionVos = new ArrayList<>();
        // 根据用户角色获取版本信息
        if(sysRolePo.getId() == rolesConfiguration.getTeacher()){// 普通教师

        }else if(sysRolePo.getId() == rolesConfiguration.getCourseLeader()){// 课程负责人

        }else if(sysRolePo.getId() == rolesConfiguration.getDepartmentHead()){// 专业负责人

        }else if(sysRolePo.getId() == rolesConfiguration.getAcademicHead()){// 教学负责人

        }else if(sysRolePo.getId() == rolesConfiguration.getAdmin()){// 管理员
            // 获取所有专业信息
            List<MajorPo> majorPos = majorMapper.selectList(null);
            // 遍历专业信息
            for(MajorPo majorPo: majorPos){
                VersionVo versionVo = new VersionVo();
                // 根据专业ID获取教学计划信息
                List<TraProgramPo> traProgramPos = traProgramMapper.selectList(
                        new LambdaQueryWrapper<TraProgramPo>().eq(TraProgramPo::getMajorId, majorPo.getId())
                );
                // 设置专业名称和教学计划信息
                versionVo.setMajor(majorPo.getMajorName());
                versionVo.setMajorVersion(traProgramPos);
                // 将版本信息添加到列表中
                versionVos.add(versionVo);
            }
        }else {
            throw new RuntimeException("用户权限错误");
        }
        return versionVos;
    }

    @Override
    public List<Major> getChartAll() {
        return majorDao.findAll();
    }

    @Override
    public void createTraProNode(TraProgramNodeDto traProgramNodeDto) {
        NoumenonPo noumenonPo = noumenonMapper.selectById(traProgramNodeDto.getId());
        String nouName = noumenonPo.getNoumenonName();
        if(nouName.equals(noumenonConfiguration.getRequire())){
            specificRequireDao.saveSpecificRequireNode(traProgramNodeDto.getNodeId(),
                    traProgramNodeDto.getName(),traProgramNodeDto.getNumber(),traProgramNodeDto.getValue());
        }else if(nouName.equals(noumenonConfiguration.getTarget())){
            specificTargetDao.saveSpecificTargetNode(traProgramNodeDto.getNodeId(),
                    traProgramNodeDto.getName(),traProgramNodeDto.getNumber(),traProgramNodeDto.getValue());
        }else if(nouName.equals(noumenonConfiguration.getBacCourses())){
            backboneCoursesDao.saveBackboneCourseNode(traProgramNodeDto.getNodeId(),
                    traProgramNodeDto.getName());
        }else if(nouName.equals(noumenonConfiguration.getTeaSteps())){
            teachingStepsDao.saveTeachingStepNode(traProgramNodeDto.getNodeId(),
                    traProgramNodeDto.getName());
        }else if(nouName.equals(noumenonConfiguration.getPoint())){
            pointDao.savePointNode(traProgramNodeDto.getNodeId(),
                    traProgramNodeDto.getName(),traProgramNodeDto.getValue());
        }else if(nouName.equals(noumenonConfiguration.getCourse())){
            if(traProgramNodeDto.getDegree().equals(degreeConfiguration.getH())){
                courseDao.saveCourseH(traProgramNodeDto.getNodeId(),
                        traProgramNodeDto.getName());
            } else if (traProgramNodeDto.getDegree().equals(degreeConfiguration.getM())) {
                courseDao.saveCourseM(traProgramNodeDto.getNodeId(),
                        traProgramNodeDto.getName());
            } else if (traProgramNodeDto.getDegree().equals(degreeConfiguration.getL())) {
                courseDao.saveCourseL(traProgramNodeDto.getNodeId(),
                        traProgramNodeDto.getName());
            }else {
                throw new RuntimeException("添加节点关系错误");
            }

        }else{
            throw new RuntimeException("添加节点本体错误");
        }
    }

    @Override
    public void deleteTraProNode(Integer nodeId) {
        majorDao.deleteByNodeId(nodeId);
    }

    @Override
    public void updateTraProNode(UpdateNodeDto updateNodeDto) {
       majorDao.updateNode(updateNodeDto.getId(), updateNodeDto.getName(),
               updateNodeDto.getNumber(),updateNodeDto.getValue());
    }
}
